package edu.unc.ils.mrc.vocabulary;

import java.io.BufferedReader;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;


import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.xml.namespace.QName;

import maui.stemmers.PorterStemmer;
import maui.stemmers.Stemmer;

import org.apache.commons.dbcp.ConnectionFactory;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDriver;
import org.apache.commons.pool.ObjectPool;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.openrdf.concepts.skos.core.Concept;
import org.openrdf.elmo.ElmoModule;
import org.openrdf.elmo.sesame.SesameManager;
import org.openrdf.elmo.sesame.SesameManagerFactory;
import org.openrdf.repository.Repository;
import org.openrdf.repository.sail.SailRepository;
import org.openrdf.rio.RDFFormat;
import org.openrdf.sail.nativerdf.NativeStore;

import edu.unc.ils.mrc.vocabulary.Term.MatchType;
import edu.unc.ils.pos.POSFilter;

/**
 * Implementation of the Vocabulary interface over an H2 embedded database.
 * @author cwillis
 *
 */
public class VocabularyTest
{
    String vocabularyName;
    String vocabularyPath;
    Stemmer stemmer = null;
    POSFilter filter = null;
    List<String> stopwords = new ArrayList<String>();

    
    public static void main(String[] args) 
    {
        try
        {
            VocabularyTest v = new VocabularyTest();
            Stemmer stemmer = new PorterStemmer();
            v.setStemmer(stemmer);
            v.setStopwords("src/main/resources/stopwords_en.txt");
            //v.importToSesame("/Users/cwillis/dev/hive/hive-data/nalt/naltStoreEn", "/Users/cwillis/dev/hive/hive-data/nalt/NAL_Thesaurus_2011_SKOS_EXPLICIT_URI_en_only.xml");
            //v.importFromSesame("/Users/cwillis/dev/hive/hive-data/nalt/naltStoreEn");
            v.doTest();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    public void doTest()
    {
        
        // Given a string, for any n, generate a set of word combinations in the form
        // A                0
        // A quick          0,1
        // A brown          0,2
        // A quick brown    0,1,2
        // quick            1
        // quick brown      1,2
        // quick fox        1,3
        // quick brown fox  1,2,3
        // brown            2
        // brown fox        2,3
        // brown jumped     2,4
        // brown fox jumped 2,3,4
        
        
        // Given a string, for any n, generate a set of word combinations in the form
        //  "A quick brown fox jumped over the lazy dog.";
        // *A                        0
        // *A quick                  0,1
        // *A brown                  0,2
        // *A fox                    0,3
        // A jumped                 0,4
        // *A quick brown            0,1,2
        // *A quick fox              0,1,3
        // A quick jumped           0,1,4
        // *A quick brown fox        0,1,2,3
        // A quick brown jumped     0,1,2,4
        // A quick brown fox jumped 0,1,2,3,4
        // *quick                    1
        // *quick brown              1,2
        // *quick fox                1,3
        // quick jumped             1,4
        // quick over               1,5
        // *quick brown fox          1,2,3
        // quick brown jumped       1,2,4
        // quick brown over         1,2,5
        // quick brown fox jumped   1,2,3,4
        // quick brown fox over     1,2,3,5
        // quick brown fox jumped over 1,2,3,4,5
        
        
        String segment = "A quick brown fox jumped over the lazy dog.";
        String[] words = segment.split(" ");
        int n = 5;
        for (int i=0; i<words.length; i++)
        {
            String key = words[i];
            System.out.println(key);
            List<String> keys = keys(words, key, i, i+n);
        }
    }
    
    public List<String> keys(String[] words, String prefix, int start, int length)
    {
        List<String> keys = new ArrayList<String>();
       
       
        for (int i=start+1; i<length; i++)
        {
            if (i > words.length-1)
                continue;
            String key = prefix + ";" + words[i];
            System.out.println(key);
            List<String> subkeys = keys(words,key, i,length);

        }
        return keys;
    }
    


    // word[0]  = A
    // word[1]  = quick
    // word[2]  = brown
    
    // word[0];
    // word[0] + word[1]
    // word[0] + word[2]
    // word[0] + word[1] + word[2]
    
    
    public void doNasa()
    {
        String text = "Background: Cotton (Gossypium hirsutum L.) fibers are trichomes that initiate from the ovule epidermis. " + 
        "Little is known about the developmental pathway causing fiber to differentiate from ovular epidermal cells even " + 
        "though limits on the number of cells that differentiate into fiber will limit yield. Results: A method was developed " + 
        "to isolate RNA from fiber initials 1 day post anthesis (dpa). Complementary DNA libraries representing 1 dpa fibers " + 
        "and other cotton tissues were sequenced and analyzed. Assembly of G. hirsutum Expressed Sequenced Tags (ESTs) identified " + 
        "over 11,000 sequences not previously represented in GenBank. New genes identified among these ESTs were represented " + 
        "on microarrays. The microarrays were used to identify genes enriched in fiber initials (1 dpa fibers) and elongating " + 
        "fibers. Analyses of Gene Ontologies (GO) of differentially expressed genes determined that terms associated with the " + 
        "membranes were statistically over represented among genes increased in expression in fiber initials and 10 dpa fibers. " + 
        "Staining ovules with a fluorescent dye confirmed an increase in Endoplasmic Reticulum (ER) occurred in fiber initials on " + 
        "the day of anthesis, persisted through 3 dpa and was absent in a fiberless mutant. Two genes similar to the " + 
        "CAPRICE/TRIPTYCHON (CPC) gene that inhibits differentiation of leaf trichomes in Arabidopsis were also characterized. " + 
        "Genes associated with novel regulation of brassinosterols, GTP mediated signal transduction and cell cycle control and " +
        "components of a Ca+2 mediated signaling pathway were identified. Staining of cellular Ca+2 indicated that fiber initials " +
        "had more Ca+2 than other ovule cells supporting a role for Ca+2 in fiber development. Conclusion: Analysis of genes " + 
        "expressed in fiber initials identified a unique stage in fiber development characterized by an increase in ER and Ca+2 " + 
        "levels that occurred between 0 and 1 dpa. The gene similar to CPC has a MYB domain but appears to lack a transcription " + 
        "activating domain similar to the Arabisopsis gene. The method used to stain the ER also can be used to count fiber " + 
        "initials and showed fiber cells develop from adjacent cells unlike leaf trichomes.";
        
        // Segment text by stopword and "thought ending punctuation such as period, colon, or semicolon"
        String[] segments = text.split(".");
        // For each segment
        for (String segment: segments)
        {
            // Create a list of all words in the segment
            String[] words = segment.split(" ");
            
            // Create list of up to five words
            String[] wordBuffer = new String[5];
        }
        // Create search key
        
        
    }
    
    
    
    
    public void setPOSFilter(POSFilter filter) 
    {
        this.filter = filter;
    }
    
    public void setStemmer(Stemmer stemmer) 
    {
        this.stemmer = stemmer;
    }
    
    protected String pseudoPhrase(String str)
    {
        String phrase = str.toLowerCase();
        String words[] = phrase.split(" ");
        List<String> stemmedWords = new ArrayList<String>();
        for (String word: words) 
        {
            word = word.replaceAll(",", "");
            word = word.replaceAll("\\.", "");
            
            word = word.replaceAll("\\(", "");
            word = word.replaceAll("\\)", "");
            word = word.replaceAll("\\'", "");
            word = word.replaceAll("-", " ");
            stemmedWords.add(stemmer.stem(word));
        }
        Collections.sort(stemmedWords);

        String pseudoPhrase = join(stemmedWords.toArray(new String[0]));
        return pseudoPhrase;
    }
    
    /**
     * Joins an array of strings to a single string.
     */
    protected static String join(String[] str) {
        String result = "";
        for(int i = 0; i < str.length; i++) {
            if (result != "") {
                result = result + " " + str[i];
            } else {
                result = str[i];
            }
        }
        return result;
    }

    
    protected String stem(String str)
    {
        if (stemmer != null)
            return stemmer.stem(str);
        else
            return str;
    }
    
    public void setStopwords(List<String> stopwords) 
    {
        this.stopwords = stopwords;
    }
    
    public void setStopwords(String path) throws IOException 
    {
        BufferedReader br = new BufferedReader(new FileReader(path));
        String word;
        while ((word = br.readLine()) != null)
            stopwords.add(word);
    }
    
    public boolean isStopword(String str) {
        return stopwords.contains(str);
    }


    public void importToSesame(String vocPath, String path) throws Exception
    {
        String indexes = "spoc,ospc";
        NativeStore store = new NativeStore(new File(vocPath), indexes);
        Repository repository = new SailRepository(store);
        repository.initialize();
        ElmoModule module = new ElmoModule();
        SesameManagerFactory factory = new SesameManagerFactory(module, repository);
        SesameManager manager = factory.createElmoManager(); 
        manager.getConnection().add(new File(path), "", RDFFormat.RDFXML);
        manager.flush();
        repository.shutDown();
        store.shutDown();

    }
    
    public void importFromSesame(String path) throws Exception
    {
        //this.vocabularyName = new File(path).getName();
        this.vocabularyPath = path;

        // Open the Sesame repository
        String indexes = "spoc,ospc";
        NativeStore store = new NativeStore(new File(vocabularyPath), indexes);
        Repository repository = new SailRepository(store);
        repository.initialize();
        ElmoModule module = new ElmoModule();
        SesameManagerFactory factory = new SesameManagerFactory(module, repository);
        SesameManager manager = factory.createElmoManager(); 
        
        FileWriter fw = new FileWriter(vocabularyName + ".out");
        for (Concept concept:  manager.findAll(Concept.class))
        {
            String prefLabel = concept.getSkosPrefLabel();
            Set<String> altLabels = concept.getSkosAltLabels();
            QName qname = concept.getQName();
            String uri = qname.getNamespaceURI() + qname.getLocalPart();
            String pseudoPhrase = pseudoPhrase(prefLabel);
            String[] words = prefLabel.split(" ");
            boolean upper = Character.isUpperCase(prefLabel.charAt(0));
            if (upper)  
            fw.write(prefLabel + "|" + words.length + "|p|" + upper + "\r\n");
            
            for (String altLabel: altLabels)
            {
                pseudoPhrase = pseudoPhrase(altLabel);
                upper = Character.isUpperCase(altLabel.charAt(0));
                words = altLabel.split(" ");
                fw.write(altLabel + "|" + words.length + "|a|" + upper + "\r\n");
            }
        }
        fw.flush();
        fw.close();
        repository.shutDown();
        store.shutDown();
    }
}
